<template>
  <div>
    <slot></slot>
    <div
      v-if="upLoading"
      class="load-show"
    >
      <p class="upwarp-progress mescroll-rotate"></p>
      <p class="upwarp-tip">加载中...</p>
    </div>
    <div
      v-if="showNoMoreData"
      class="load-show"
    >已加载全部</div>
  </div>
</template>
<script>
export default {
  name: 'PullUpList',
  props: {
    up: {
      type: Object,
      default: () => {
        return {
          noMoreSize: 10,
          page: { size: 10 }
        }
      }
    },
    getListData: {
      type: Function,
      required: true
    }
  },
  data() {
    return {
      page: {
        num: 1,
        size: 10
      },
      count: 0,
      nodata: false,
      upLoading: false, // 是否是上拉加载中,为了保护上拉加载不多次触发
      loadAll: false, // 数据是否全部加载完
      refreshEvent: new Event('dataRefresh'), // 下拉刷新的事件
      pullUpEvent: new Event('dataUpLoad') // 下拉刷新的事件
    }
  },
  computed: {
    // 当当前页不是第一页，且数据全部加载完成时展示“已加载全部”
    showNoMoreData() {
      return this.page.num !== 1 && this.loadAll
    }
  },
  created() {
    this.refreshEvent.successCallback = this.pullDownFinish
    this.refreshEvent.failureCallback = this.pullDownError
    this.pullUpEvent.successCallback = this.pullUpFinish
    this.pullUpEvent.failureCallback = this.pullUpError
    this.addPullUpHandler()
    window.onRefresh = () => {
      this.firePullDownEvent()
    }
  },
  mounted() {
    this.$nextTick(() => {
      setTimeout(() => {
        this.firePullUpEvent()
      }, 200)
    })
  },
  destroyed() {
    this.removePullUpHandler()
  },
  methods: {
    // 添加上拉监听
    addPullUpHandler() {
      // window.onscroll = this.onScrollFunc
      document.addEventListener('scroll', this.onScrollFunc, false)
    },
    // 移除上拉监听
    removePullUpHandler() {
      // window.onscroll = () => {}
      document.removeEventListener('scroll', this.onScrollFunc, false)
    },
    // 获取数据的协议
    upCallback(page) {
      this.getListData(page.num, page.size).then(({ length, count }) => {
        this.nodata = false
        this.count = count || 0
        if (page.num === 1) {
          this.endXBRefresh()
        }
        // console.log(length, this.count)
        this.$nextTick(() => {
          // console.log(this.mescroll.endBySize)
          this.mescroll.endBySize(length, this.count)
        })

        if (this.count <= 0) {
          this.nodata = true
          this.hideNoMoreHtml()
        }
      }).catch(() => {
        if (page.num === 1) { this.endXBRefresh() }
        if (this.count > 0) {
          // 联网失败的回调,隐藏下拉刷新和上拉加载的状态;
          this.mescroll.endErr()
        } else {
          // 第一页获取数据失败时展示无数据
          this.nodata = true
          this.mescroll.endBySize(0, this.count)
        }
      })
    },
    // 分發下拉刷新的事件
    firePullDownEvent() {
      // 下拉刷新了就把当前页码置为1
      this.page.num = 1
      this.loadAll = false
      this.refreshEvent.page.num = this.page.num
      window.document.dispatchEvent(this.refreshEvent)
      this.upCallback({
        num: this.page.num,
        size: this.up.page.size
      })
    },
    pullDownFinish(pageSize, nowPageLength, total) {
      if (pageSize && nowPageLength && total) {
        this.pullUpFinish(pageSize, nowPageLength, total)
      }
      this.finishRefresh()
    },
    pullDownError() {
      this.pullUpError()
      this.finishRefresh()
    },
    // 下拉结束调用
    finishRefresh() {
      console.log('下拉刷新结束啦~')
      if (window.x_ui) {
        window.x_ui.onFinishRefresh(msg => {
          console.log(msg)
        }, err => {
          console.error(err)
        })
      }
    },
    // 分发上拉加载的事件，需要的组件监听
    firePullUpEvent() {
      this.upLoading = true
      this.pullUpEvent.page.num = this.page.num
      window.document.dispatchEvent(this.pullUpEvent)
      this.upCallback({
        num: this.page.num,
        size: this.up.page.size
      })
    },
    // 上拉刷新结束的回调
    // pageSize 一页的数据量
    // total 总数据量
    pullUpFinish(pageSize, total) {
      this.upLoading = false
      // 当前页的数据量小于一页的数据量时
      if (pageSize * this.page.num >= total) {
        this.loadAll = true
      } else {
        this.loadAll = false
        this.page.num++
      }
    },
    // 上拉加载，获取数据出错时调用该方法
    pullUpError() {
      this.upLoading = false
    },
    // 滚动函数
    onScrollFunc(e) {
      // console.log('滚动了-20')
      if (!this.loadAll && !this.upLoading && this.isScrollToEnd()) {
        this.firePullUpEvent()
      }
    },
    // 是否滑动到底部
    isScrollToEnd() {
      return this.getScrollTop() + this.getWindowHeight() >= this.getScrollHeight() - 20
    },
    getScrollTop() {
      var scrollTop = 0
      var bodyScrollTop = 0
      var documentScrollTop = 0
      if (document.body) {
        bodyScrollTop = document.body.scrollTop
      }
      if (document.documentElement) {
        documentScrollTop = document.documentElement.scrollTop
      }
      scrollTop = (bodyScrollTop - documentScrollTop > 0) ? bodyScrollTop : documentScrollTop
      // console.log('scrollTop' + scrollTop)
      return scrollTop
    },
    // 文档的总高度
    getScrollHeight() {
      var scrollHeight = 0
      var bodyScrollHeight = 0
      var documentScrollHeight = 0
      if (document.body) {
        bodyScrollHeight = document.body.scrollHeight
      }
      if (document.documentElement) {
        documentScrollHeight = document.documentElement.scrollHeight
      }
      scrollHeight = (bodyScrollHeight - documentScrollHeight > 0) ? bodyScrollHeight : documentScrollHeight
      // console.log('scrollHeight' + scrollHeight)
      return scrollHeight
    },
    getWindowHeight() {
      var windowHeight = 0
      if (document.compatMode === 'CSS1Compat') {
        windowHeight = document.documentElement.clientHeight
      } else {
        windowHeight = document.body.clientHeight
      }
      // console.log('windowHeight' + windowHeight)
      return windowHeight
    }
  }
}
</script>
<style scoped>
.load-show {
  text-align: center;
  vertical-align: middle;
  padding: 20px 0;
  color: gray;
  font-size: 12px; /*px*/
}
.upwarp-progress {
  display: inline-block;
  width: 12px; /*no*/
  height: 12px; /*no*/
  border-radius: 50%;
  border: 1px solid gray; /*no*/
  border-bottom-color: transparent;
  vertical-align: middle;
}
.upwarp-tip {
  display: inline-block;
  color: gray;
  vertical-align: middle;
  margin-left: 8px;
}

/*旋转动画*/
.mescroll-rotate {
  -webkit-animation: mescrollRotate 0.6s linear infinite;
  animation: mescrollRotate 0.6s linear infinite;
}

@-webkit-keyframes mescrollRotate {
  0% {
    -webkit-transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
  }
}

@keyframes mescrollRotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>
